
export default class CanvasRenderer {
  constructor(ctx, options) {
    this.ctx = ctx;
    this.options = options || {};
    this.areaListMap = this._getAreaListMap(this.options?.areaList||[]);
  }

  /* ---------- 工具 ---------- */
  _roundRect(x, y, w, h, r) {
    const ctx = this.ctx;
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.arcTo(x + w, y, x + w, y + h, r);
    ctx.arcTo(x + w, y + h, x, y + h, r);
    ctx.arcTo(x, y + h, x, y, r);
    ctx.arcTo(x, y, x + w, y, r);
    ctx.closePath();
  }
  _roundRect_left(x, y, w, h, r) {
    const ctx = this.ctx;
    ctx.beginPath();
    ctx.moveTo(x + w, y + h);
    ctx.arcTo(x, y + h, x, y + h - r, r);
    ctx.lineTo(x, y + r);
    ctx.arcTo(x, y, x + r, y, r);
    ctx.lineTo(x + w - r, y);
    ctx.arcTo(x + w, y, x + w, y + r, r);
    ctx.lineTo(x + w, y + h / 2);
  }

  _roundRect_right(x, y, w, h, r) {
    const ctx = this.ctx;
    ctx.beginPath();
    ctx.moveTo(x, y + h);
    ctx.arcTo(x + w, y + h, x + w, y + h - r, r);
    ctx.lineTo(x + w, y + r);
    ctx.arcTo(x + w, y, x + w - r, y, r);
    ctx.lineTo(x + r, y);
    ctx.arcTo(x, y, x, y + r, r);
    ctx.lineTo(x, y + h / 2);
  }
  // 座位状态样式缓存
  _getAreaListMap(areaList){
    const { AREA_ID } = this.options.SEAT_FIELDS;
     return areaList.reduce((obj, area) => {
          obj[area[AREA_ID]] = area;
          return obj;
     }, {}); 
  }
  /* ---------- 1. 清屏 ---------- */
  clear(x, y, width, height) {
    this.ctx.clearRect(x, y, width, height);
  }

  /* ---------- 2. 座位主入口 ---------- */
  drawSeatMap({ panX, panY, cellSize, seatCol,seatList, seatRow, imageGou }) {
    const ctx = this.ctx;
    const { ROW_ID, COLUMN_ID } = this.options.SEAT_FIELDS;
    ctx.save();
    ctx.translate(panX, panY);
    ctx.lineWidth = 1;
    seatList.forEach(seat => {
      seat.points = this.drawSeat(seat, seat[COLUMN_ID] * cellSize, seat[ROW_ID] * cellSize, cellSize,imageGou);
    });
    ctx.restore();
  }

  /* ---------- 3. 单个座位 ---------- */
  drawSeat(seat, startX, startY, cellSize, imageGou) {
    const ctx = this.ctx;
    const { SINGLE, COUPLE_LEFT, COUPLE_MIDDLE, COUPLE_RIGHT } = this.options.SEAT_TYPE;
    const { SELECTED } = this.options.SEAT_STATUS;
    const { STATUS_NAME,TYPE_NAME } = this.options.SEAT_FIELDS;
    const radius = cellSize / 5;
    const margin = radius;
    const seatType = seat[TYPE_NAME];
    // 颜色
    const colors = this._getSeatColors(seat);
    ctx.fillStyle = colors.fillStyle;
    ctx.strokeStyle = colors.strokeStyle;

    let x, y, w, h;
    if (seatType === SINGLE) {
      x = startX + margin / 2;
      y = startY + margin / 2;
      w = cellSize - margin;
      h = cellSize - margin;
      this._roundRect(x, y, w, h, radius);
      ctx.fill();
      ctx.stroke();
    }
    if (seatType === COUPLE_LEFT) {
      x = startX + margin / 2;
      y = startY + margin / 2;
      w = cellSize - margin / 2;
      h = cellSize - margin;

      this._roundRect_left(x, y, w, h, radius);
      ctx.fill();
      ctx.stroke();
    }
    if (seatType === COUPLE_MIDDLE || seatType === COUPLE_RIGHT) {
      x = startX;
      y = startY + margin / 2;
      w = cellSize - margin / 2;
      h = cellSize - margin;
      this._roundRect_right(x, y, w, h, radius);
      ctx.fill();
      ctx.stroke();
    }

    // 已选勾勾
    if (seat[STATUS_NAME] === SELECTED) {
      ctx.drawImage(imageGou, startX + cellSize / 4, startY + cellSize / 4, cellSize / 2, cellSize / 2);
    }
    return {
      startX: x,
      startY: y,
      endX: x + w,
      endY: y + h,
    };
  }

  _getSeatColors(seat) {
    
    const { STATUS_NAME, AREA_ID } = this.options.SEAT_FIELDS;
    const seatStatus = seat[STATUS_NAME];
    const seatArea   = seat[AREA_ID];
    if (!this.statusStyleMap) this.statusStyleMap = new Map();
    if (this.statusStyleMap.has(`${seatStatus}-${seatArea}`)) {
      return this.statusStyleMap.get(`${seatStatus}-${seatArea}`)
    };
    
    const { DISABLED, LOCKED, SOLD, AVAILABLE, SELECTED } = this.options.SEAT_STATUS;
    const {  SEAT_STYLE } = this.options;

    this.statusStyleMap.set(`${seatStatus}-${seatArea}`, { fillStyle: 'transparent', strokeStyle: 'transparent' });
    this.statusStyleMap.set(`${DISABLED}-${seatArea}`, SEAT_STYLE.DISABLED);
    this.statusStyleMap.set(`${LOCKED}-${seatArea}`, SEAT_STYLE.LOCKED);
    this.statusStyleMap.set(`${SOLD}-${seatArea}`, SEAT_STYLE.SOLD);
    this.statusStyleMap.set(`${SELECTED}-${seatArea}`, SEAT_STYLE.SELECTED);
    this.statusStyleMap.set(`${AVAILABLE}-${seatArea}`, {
      fillStyle: SEAT_STYLE.AVAILABLE.fillStyle,
      strokeStyle: this.areaListMap[seat[AREA_ID]]?.strokeStyle || SEAT_STYLE.AVAILABLE.strokeStyle,
    });
    return this.statusStyleMap.get(`${seatStatus}-${seatArea}`);
  }

  /* ---------- 4. 中线 + 文字 ---------- */
  drawCenterLine({ panX, panY, seatCol, seatRow, cellSize, title }) {
    const ctx = this.ctx;
    ctx.save();
    ctx.translate(panX, panY);
    ctx.beginPath();
    ctx.setLineDash([3, 3]);
    ctx.strokeStyle = '#999';
    ctx.moveTo(seatCol * cellSize / 2, 0);
    ctx.lineTo(seatCol * cellSize / 2, seatRow * cellSize + 20);
    ctx.stroke();
    ctx.setLineDash([]);
    
    ctx.beginPath();
    ctx.arc(seatCol * cellSize / 2, seatRow * cellSize + 20, 0.5, 0, 2 * Math.PI); // 绘制圆
    ctx.stroke();
    ctx.restore();

    if(!title) return;
    ctx.save();
    ctx.translate(panX, panY);
    ctx.fillStyle = '#d8d8d8';
    ctx.font = '14px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(title, seatCol * cellSize / 2, seatRow * cellSize + 40);
    ctx.restore();
  }

  /* ---------- 5. 排号侧边栏 ---------- */
  drawRowLabels({ panY, cellSize, seatArray }) {
    const ctx = this.ctx;
    const x = 4, w = 16, radius = w / 2;
    const h = cellSize * seatArray.length;
    ctx.save();
    ctx.translate(0, panY);
    ctx.beginPath();
    ctx.moveTo(x + radius, 0);
    ctx.arcTo(x + w, 0, x + w, radius, radius);
    ctx.arcTo(x + w, h, x + w - radius, h, radius);
    ctx.arcTo(x, h, x, h - radius, radius);
    ctx.arcTo(x, 0, x + radius, 0, radius);
    ctx.fillStyle = 'rgba(150,150,150,0.8)';
    ctx.fill();
    ctx.fillStyle = '#fff';
    ctx.font = '10px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    seatArray.forEach((_, rowId) => {
      ctx.fillText(String(rowId), x + w / 2, rowId * cellSize + cellSize / 2);
    });
    ctx.restore();
  }

  /* ---------- 6. 屏幕 ---------- */
  drawScreen({ panX, imageScreen, hallName, cellSize, seatCol, canvasWidth,hallHeight }) {
    const ctx = this.ctx;
    const screenW = canvasWidth / 2;
    const screenH = (imageScreen.height / imageScreen.width) * screenW;
    const centerX = cellSize * seatCol / 2;
    ctx.save();
    ctx.clearRect(0, 0, canvasWidth, hallHeight);
    ctx.translate(panX, 0);
    ctx.drawImage(imageScreen, centerX - screenW / 2, 0, screenW, screenH);
    ctx.fillStyle = '#000';
    ctx.font = '10px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(hallName || '', centerX, screenH - 5);
    ctx.restore();
  }

 /* ---------- 8. 虚拟缩略图 ---------- */
drawMiniMap({miniMapShow,seatList,seatCol,seatRow,canvasWidth,hallHeight,panX,cellSize: realCellSize}) {
    if (!miniMapShow) return;

    const ctx = this.ctx;
    const miniCellSize = 6;
    const margin = 1;

    const { DISABLED, LOCKED, SOLD, AVAILABLE, SELECTED } = this.options.SEAT_STATUS;
    const { SINGLE, COUPLE_LEFT, COUPLE_MIDDLE, COUPLE_RIGHT } = this.options.SEAT_TYPE;
    const { STATUS_NAME, TYPE_NAME,ROW_ID,COLUMN_ID } = this.options.SEAT_FIELDS;
    const contentWidth  = miniCellSize * seatCol;
    const contentHeight = miniCellSize * seatRow;
    const virtualWidth  = miniCellSize * (seatCol + 2);
    const virtualHeight = miniCellSize * (seatRow + 2);
    const startX = (virtualWidth - contentWidth) / 2;
    const startY = hallHeight - 40 + miniCellSize;

    
    ctx.save();

    /* 1. 背景 */
    ctx.fillStyle = 'rgba(0,0,0,0.6)';
    ctx.fillRect(0, hallHeight - 40, virtualWidth, virtualHeight);

    /* 2. 画座位 */
    seatList.forEach(seat => {
      let x = startX + seat[COLUMN_ID] * miniCellSize;
      let y = startY + seat[ROW_ID] * miniCellSize;

      let rectStartX = x + margin;
      let rectStartY = y + margin;
      let rectWidth  = miniCellSize - margin * 2;
      let rectHeight = miniCellSize - margin * 2;
      if (seat[TYPE_NAME] !== SINGLE) {
        rectWidth = miniCellSize - margin;
      }
      if (seat[TYPE_NAME] === COUPLE_MIDDLE || seat[TYPE_NAME] === COUPLE_RIGHT) {
        rectStartX = x;
      }

      let fillStyle = 'transparent';
      if (seat[STATUS_NAME] === AVAILABLE) fillStyle = '#fff';
      if (seat[STATUS_NAME] === SELECTED)  fillStyle = '#0ed7b8';
      if (seat[STATUS_NAME] === SOLD)      fillStyle = 'red';

      ctx.fillStyle = fillStyle;
      ctx.fillRect(rectStartX, rectStartY, rectWidth, rectHeight);
    });

    /* 3. 中线 */
    ctx.beginPath();
    ctx.setLineDash([3, 3]);
    ctx.strokeStyle = '#999';
    ctx.moveTo(startX + contentWidth / 2, startY);
    ctx.lineTo(startX + contentWidth / 2, startY + contentHeight);
    ctx.stroke();
    ctx.setLineDash([]);

    /* 4. 可视区域红框 */
    const realContentWidth = realCellSize * seatCol;
    const virtualBoxWidth  = (canvasWidth / realContentWidth) * contentWidth;
    const virtualBoxHeight = contentHeight;

    let virtualStartX = startX + ((-panX) / realContentWidth) * contentWidth;
    let virtualStartY = startY;
    virtualStartX = Math.min(virtualStartX, virtualWidth - virtualBoxWidth);

    ctx.strokeStyle = 'red';
    ctx.strokeRect(virtualStartX, virtualStartY, virtualBoxWidth, virtualBoxHeight);

    ctx.restore();
  }
}